package com.web.account.service;

import com.web.account.entity.Account;
import com.web.account.mapper.AccountMapper;
import com.web.common.BaseResult;
import com.web.common.PendingAmend;
import com.web.common.ReturnCode;
import com.web.common.enums.BaseStatus;
import com.web.common.enums.BuyOrSell;
import com.web.config.ConsumerRunner;
import com.web.currency.entity.Currency;
import com.web.customer.controller.CustomerController;
import com.web.customer.entity.Customer;
import com.web.customer.mapper.CustomerMapper;
import com.web.pendingList.entity.PendingList;
import com.web.pendingList.service.PendingListService;
import io.swagger.models.auth.In;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author wenzhuo
 * @create 2024-01-09 2024/1/9
 */
@Service
public class AccountService implements PendingAmend {
    @Resource
    private AccountMapper accountMapper;

    @Resource
    private PendingListService pendingService;


    public List<Account> getAccountList(String accountNo, String currency,Integer customerNo){
       return accountMapper.getAccounts(accountNo,currency,customerNo);
    }

    public Integer addAccount(Account account){
        return accountMapper.addAccount(account);
    }

    public Integer updateAccount(Account account){
       return accountMapper.amendAccount(account);
    };

    public Integer deleteAccount(String accountNo){
        return accountMapper.logicalDeleteAccount(accountNo);
    };

    public List<Account> checkData(Account account){
        return accountMapper.checkDuplicateDate(account);
    };

    public List<Account> getAccountWithCustomer(Account account) {
        return  accountMapper.getAccountData(account);
    }

    public Integer physicsDeleteAccount(Integer customerNo){
        return accountMapper.physicsDeleteAccount(customerNo);
    };

    public Integer ModifyPendingNumber(Account accountOld) {
        return accountMapper.updatePendingNumber(accountOld);
    }

    public Integer addTemporaryData(Account accountNew) {
        return accountMapper.addTemporaryAccount(accountNew);
    }

    public Integer generateAccountByCustomer(Customer customer) {

        List<Account> accounts = new ArrayList();

        //从optionCurrencyMap中获取货币信息
        List<String> currencies = CustomerController.optionCurrencyMap.get(customer.getCustomerName());


        for (String currency: currencies) {
            Account account = new Account();
            account.setAccountBalance(new BigDecimal("50000"));
            account.setCustomerNo(customer.getCustomerNo());
            account.setRemark(generateRemark(customer,currency,BuyOrSell.B.getDirection()));
            account.setCurrency(currency);
            account.setAccountType(BuyOrSell.B.getDirection());
            accounts.add(account);
        }

        for (String currency: currencies) {
            Account account = new Account();
            account.setAccountBalance(new BigDecimal("50000"));
            account.setCustomerNo(customer.getCustomerNo());
            account.setRemark(generateRemark(customer,currency,BuyOrSell.S.getDirection()));
            account.setCurrency(currency);
            account.setAccountType(BuyOrSell.S.getDirection());
            accounts.add(account);
        }
        System.out.println(accounts.toString());

        return  accountMapper.bulkInsertAccount(accounts);
    }

    private String generateRemark(Customer customer,String currency,String buyOrSell) {
        StringBuilder builder = new StringBuilder();
        builder.append("客户").append(customer.getCustomerNo()).append("的").append(currency)
                .append("的").append(BuyOrSell.generateDescription(buyOrSell)).append("账户");

        return builder.toString();
    }

    @Override
    @Transactional
    public BaseResult rejectAddPending(PendingList pendingTxn) {
        //根据PendingNumber查询出Account数据
        Account account = accountMapper.getAccountByPendingNumber(pendingTxn.getPendingNum());

        //将Pending记录的状态改为REJ.
        if(pendingService.updatePendingTxn(PendingList.makeReject(pendingTxn)) < 0){
            return new BaseResult(BaseStatus.PENDING__DATA_EXCEPTION.getCode(),BaseStatus.PENDING__DATA_EXCEPTION.getDesc());
        }

        //将Account数据进行物理删除.
        if(accountMapper.physicsDeleteAccountByPendingNumber(account.getPendingNumber()) <= 0){
            return new BaseResult(BaseStatus.ACCOUNT_DATA_EXCEPTION.getCode(),BaseStatus.ACCOUNT_DATA_EXCEPTION.getDesc());
        }

        return new BaseResult(BaseStatus.SUCCESS.getCode(),BaseStatus.PENDING_REJECT_SUCCESS.getDesc());
    }

    @Override
    @Transactional
    public BaseResult approveAddPending(PendingList pendingTxn) {
        //根据PendingNumber查询出Account数据
        Account account = accountMapper.getAccountByPendingNumber(pendingTxn.getPendingNum());

        //将Pending记录的状态改为APP.
        if(pendingService.updatePendingTxn(PendingList.makeApprove(pendingTxn)) < 0){
            return new BaseResult(BaseStatus.PENDING__DATA_EXCEPTION.getCode(),BaseStatus.PENDING__DATA_EXCEPTION.getDesc());
        }

        //将Account数据的APPROVE标记为Y,PendingNumber设置为NULL即可.
        if(accountMapper.updateApproved(account.getPendingNumber()) <= 0){
            return new BaseResult(BaseStatus.ACCOUNT_DATA_EXCEPTION.getCode(),BaseStatus.ACCOUNT_DATA_EXCEPTION.getDesc());
        }

        return new BaseResult(BaseStatus.SUCCESS.getCode(),BaseStatus.PENDING_APPROVE_SUCCESS.getDesc());
    }

    @Override
    @Transactional
    public BaseResult rejectDeletePending(PendingList pendingTxn) {
        //根据PendingNumber查询出Account数据
        Account account = accountMapper.getAccountByPendingNumber(pendingTxn.getPendingNum());

        //将Pending记录的状态修改为REJ
        if(pendingService.updatePendingTxn(PendingList.makeReject(pendingTxn)) < 0){
            return new BaseResult(BaseStatus.PENDING__DATA_EXCEPTION.getCode(),BaseStatus.PENDING__DATA_EXCEPTION.getDesc());
        }

        //将Account数据的PendingNumber设置为NULL即可.
        if(accountMapper.updateApproved(account.getPendingNumber()) <= 0){
            return new BaseResult(BaseStatus.ACCOUNT_DATA_EXCEPTION.getCode(),BaseStatus.ACCOUNT_DATA_EXCEPTION.getDesc());
        }

        return new BaseResult(BaseStatus.SUCCESS.getCode(),BaseStatus.PENDING_REJECT_SUCCESS.getDesc());
    }

    @Override
    @Transactional
    public BaseResult approveDeletePending(PendingList pendingTxn) {
        //将Pending记录的状态修改为APP
        if(pendingService.updatePendingTxn(PendingList.makeApprove(pendingTxn)) < 0){
            return new BaseResult(BaseStatus.PENDING__DATA_EXCEPTION.getCode(),BaseStatus.PENDING__DATA_EXCEPTION.getDesc());
        }

        //根据PendingNumber物理删除Account数据
        if(accountMapper.physicsDeleteAccountByPendingNumber(pendingTxn.getPendingNum()) <= 0){
            return new BaseResult(BaseStatus.FCE_DELETE_FAIL.getCode(),BaseStatus.FCE_DELETE_FAIL.getDesc());
        }

        return new BaseResult(BaseStatus.SUCCESS.getCode(),BaseStatus.PENDING_APPROVE_SUCCESS.getDesc());
    }

    @Override
    @Transactional
    public BaseResult rejectModifyPending(PendingList pendingTxn) {
        //根据PendingNumber查询出AccountOld数据
        Account accountOld = accountMapper.getAccountByPendingNumber(pendingTxn.getPendingNum());

        //将PendingTxn的状态修改为REJ
        if(pendingService.updatePendingTxn(PendingList.makeReject(pendingTxn)) < 0){
            return new BaseResult(BaseStatus.PENDING__DATA_EXCEPTION.getCode(),BaseStatus.PENDING__DATA_EXCEPTION.getDesc());
        }

        //物理删除临时表中的数据
        if(accountMapper.physicsDeleteAccountTmp(accountOld.getPendingNumber()) <= 0){
            return new BaseResult(BaseStatus.FCE_DELETE_FAIL.getCode(),BaseStatus.FCE_DELETE_FAIL.getDesc());
        }

        //将AccountOld数据的PendingNumber设置为null
        if( accountMapper.updateApproved(accountOld.getPendingNumber()) <= 0){
            return new BaseResult(BaseStatus.FCE_UPDATE_FAIL.getCode(),BaseStatus.FCE_UPDATE_FAIL.getDesc());

        }

        return new BaseResult(BaseStatus.SUCCESS.getCode(),BaseStatus.PENDING_REJECT_SUCCESS.getDesc());
    }

    @Override
    @Transactional
    public BaseResult approveModifyPending(PendingList pendingTxn) {
        //根据PendingNumber查询出AccountOld数据
        Account accountOld = accountMapper.getAccountByPendingNumber(pendingTxn.getPendingNum());

        //根据PendingNumber查询出AccountNew数据
        Account accountNew = accountMapper.getTemporaryAccount(pendingTxn.getPendingNum());

        //将PendingTxn的状态修改为APP
        if(pendingService.updatePendingTxn(PendingList.makeApprove(pendingTxn)) < 0){
            return new BaseResult(BaseStatus.PENDING__DATA_EXCEPTION.getCode(),BaseStatus.PENDING__DATA_EXCEPTION.getDesc());
        }

        //修改customerOld的数据
        accountOld.setAccountBalance(accountNew.getAccountBalance());
        accountOld.setRemark(accountNew.getRemark());
        if(accountMapper.updateSourceAccount(accountOld) <= 0){
            return new BaseResult(BaseStatus.ACCOUNT_DATA_EXCEPTION.getCode(),BaseStatus.ACCOUNT_DATA_EXCEPTION.getDesc());
        };

        //物理删除临时表中的数据
        if(accountMapper.physicsDeleteAccountTmp(accountOld.getPendingNumber()) <= 0){
            return new BaseResult(BaseStatus.FCE_DELETE_FAIL.getCode(),BaseStatus.FCE_DELETE_FAIL.getDesc());
        }

        return new BaseResult(BaseStatus.SUCCESS.getCode(),BaseStatus.PENDING_APPROVE_SUCCESS.getDesc());
    }

    public Account getBuyAccountByCurrency(String buyCurrency,Integer customerNo) {
        return accountMapper.getBuyAccountByCurrency(buyCurrency,customerNo);

    }

    public Account getSellAccountByCurrency(String sellCurrency,Integer customerNo) {
        return accountMapper.getSellAccountByCurrency(sellCurrency,customerNo);
    }

    public Integer increaseAmount(Account buyAccount) {
        return accountMapper.updateAmount(buyAccount);
    }

    public Integer reduceAmount(Account sellAccount) {
        return accountMapper.updateAmount(sellAccount);
    }
}
